<template>
  <a-drawer v-model:visible="LAYER.visible" :title="LAYER.title" :width="LAYER.width"
            :closable="LAYER.closable" :mask-closable="LAYER.maskClosable" :esc-to-close="LAYER.escToClose"
            :unmount-on-close="LAYER.unmountOnClose" :footer="LAYER.footer" :ok-text="LAYER.okText"
            :ok-loading="LAYER.okLoading" :cancel-text="LAYER.cancelText" :on-before-ok="onSubmit" @close="onCancel">
    <!--表单开始-->

    <a-form ref="formRef" :model="formState" layout="vertical" :rules="ROLE_EDIT.RULES">
      <a-row :gutter="12">
        <a-col :span="8">
          <a-form-item label="角色代码" field="code">
            <a-input v-model="formState.code" allow-clear placeholder="请填写角色代码" :disabled="isUpdate"/>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="角色名称" field="name">
            <a-input v-model="formState.name" allow-clear placeholder="请填写角色名称"/>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="适用账号类型" field="accountType">
            <smart-dict v-model="formState.accountType" :url="DictOptions.AccountType" :disabled="isUpdate"/>
          </a-form-item>
        </a-col>

        <a-col :span="24">
          <a-form-item label="角色描述" field="description">

            <a-textarea v-model="formState.description" placeholder="请填写角色描述"
                        :auto-size="{ minRows: 2, maxRows: 5 }"/>
          </a-form-item>
        </a-col>


        <a-col :span="24">


          <a-card title="功能设置">

            <template #extra>
              <a-link @click="treeCtr.toggle()">
                {{ treeCtr.expandedKeys.length > 0 ? '收起全部' : '展开全部' }}
              </a-link>
            </template>

            <a-form-item field="apiTokens" hide-label>


              <a-checkbox-group v-model="formState.apiTokens" style="width: 100%">
                <a-tree
                    v-model:expanded-keys="treeCtr.expandedKeys"
                    block-node
                    :data="treeCtr.treeData"
                    :field-names="treeCtr.filedName"
                    show-line>
                  <template #extra="nodeData">
                    <div v-if="nodeData.apiList.length" class="tokenBox">
                      <a-link style="margin-right: 6px" title="仅提供全选快捷操作" @click.prevent="treeCtr.selectAll(nodeData.apiList)">全选</a-link>
                      <a-checkbox v-for="(item , index ) in nodeData.apiList" :key="index" :value="item.value"> {{ item.label }}
                      </a-checkbox>
                    </div>
                  </template>
                </a-tree>
              </a-checkbox-group>
            </a-form-item>
          </a-card>
        </a-col>
      </a-row>


    </a-form>
    <!--表单结束-->
  </a-drawer>
</template>

<script lang="ts" setup>
import {reactive} from 'vue'
import {EditDrawer} from '@/libs/core'
import {ROLE_EDIT} from "../resource/form";
import {SystemHttp} from '../resource/http'
import {SystemOptions, DictOptions} from "@/libs/options";
import {RequestUtil, TreeUtil} from "@/utils";

const props = defineProps({record: {type: Object, required: true}})
const emit = defineEmits(['cancel'])

const {addRole, updateRole} = SystemHttp
const config = {tplRecord: ROLE_EDIT.BODY, rawRecord: props.record, rowKey: 'id', emit}

const service = new EditDrawer(config).setAddRequest(addRole).setUpdateRequest(updateRole)

// 获取目录对应的菜单ID集合
const getCheckMenuIds = (sourceArr, checkedArr): any[] => {
  const resultArray = []
  const loopFindParentId = findId => {
    for (let i = 0; i < sourceArr.length; i++) {
      if (sourceArr[i].value === findId) {
        resultArray.push(sourceArr[i].value)
        if (sourceArr[i].parent !== '0') loopFindParentId(sourceArr[i].parent)
        break
      }
    }
    return resultArray
  }

  sourceArr.forEach(item => {

    const b = checkedArr.some(m => item.apiList.map(x => x.value).includes(m))
    if (b) loopFindParentId(item.value)
  })

  return [...new Set(resultArray)]
}


const {formRef, formState, LAYER, isUpdate, onCancel, onSubmit} = service
const treeCtr = reactive({
  sourceData: [],
  treeData: [],
  expandedKeys: [],
  filedName: {
    key: 'value',
  },
  loadTree: async () => {
    const {data} = await RequestUtil.getAjax(SystemOptions.MenuAndApiOptions)
    treeCtr.sourceData = data
    treeCtr.treeData = TreeUtil.listToTree(data)
    await treeCtr.toggle();
  },
  selectAll: data => {

    const tokens = data.map(item => item.value)
    const result = [...formState.value.apiTokens, ...tokens];
    formState.value.apiTokens = [...new Set(result)]
  },
  toggle: () => {
    if (treeCtr.expandedKeys.length > 0) {
      treeCtr.expandedKeys = []
    } else {
      treeCtr.expandedKeys = treeCtr.sourceData.filter(x => x.attribute !== 'PAGE').map(x => x.value)
    }
  }
})
service.afterValidateHandler = () => {

  formState.value.menuIds = getCheckMenuIds(treeCtr.sourceData, formState.value.apiTokens)
  return true
}
LAYER.title = isUpdate ? '修改角色' : '新建角色'


treeCtr.loadTree()


</script>


<style lang="less" scoped>

:deep(.arco-tree-node) {
  align-items: baseline;

  .tokenBox {
    max-width: 500px;
    text-align: right;
  }
}
</style>